<template>
  <div class="console-container">
    <div style="height: 100%; width: 100%; background: #002833;">
      <div id="terminal" ref="terminal"/>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import 'xterm/css/xterm.css'
import { Terminal } from 'xterm'
import Socket from '@/components/shell/socket/Socket'

@Component
export default class Shell extends Vue {
  term: Terminal = new Terminal();

  socket = new Socket('127.0.0.1', 8080, 'webssh')

  // 行列
  rows = 40
  cols = 120;

  mounted () {
    const _this = this
    this.initSocket()
    // 获取容器宽高/字号大小，定义行数和列数
    const con: HTMLElement | null = document.querySelector('.indexContainer')
    if (con !== null) {
      _this.rows = con.offsetHeight / 16 - 5
      _this.cols = con.offsetWidth / 14
    }

    // 实例化terminal实例
    const term = new Terminal({
      rendererType: 'canvas', // 渲染类型
      rows: this.rows, // 行数
      cols: this.cols, // 不指定行数，自动回车后光标从下一行开始
      convertEol: true, // 启用时，光标将设置为下一行的开头
      //   scrollback: 50, //终端中的回滚量
      disableStdin: false, // 是否应禁用输入。
      cursorStyle: 'underline', // 光标样式
      cursorBlink: true, // 光标闪烁
      theme: {
        foreground: '#7e9192', // 字体
        background: '#002833', // 背景色
        cursor: 'help' // 设置光标
      }
    })

    // 挂载到dom
    const terminalContainer: HTMLElement | null = document.getElementById(
      'terminal'
    )
    if (terminalContainer !== null) {
      term.open(terminalContainer)
      term.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ')
    }

    // / **
    //     *添加事件监听器，用于按下键时的事件。事件值包含
    //     *将在data事件以及DOM事件中发送的字符串
    //     *触发了它。
    //     * @返回一个IDisposable停止监听。
    //  * /
    //   / ** 更新：xterm 4.x（新增）
    //  *为数据事件触发时添加事件侦听器。发生这种情况
    //  *用户输入或粘贴到终端时的示例。事件值
    //  *是`string`结果的结果，在典型的设置中，应该通过
    //  *到支持pty。
    //  * @返回一个IDisposable停止监听。
    //  * /
    // 支持输入与粘贴方法
    term.onData((key: string) => {
      this.onSend('command', key)
    })

    this.term = term
  }

  private initSocket () {
    console.log('initSocket')
    this.socket.connect(
      () => {
        // 建立连接后发送初始化请求
        this.onSend('connect', 'init')
      },
      (msg: string) => {
        this.term.write(msg)
      }
    )
  }

  onSend (operate: string = 'command', command: string) {
    this.socket.sendCmd(operate, command)
  }

  // 删除左右两端的空格
  trim (str: string) {
    return str.replace(/(^\s*)|(\s*$)/g, '')
  }
}
</script>

<style scoped></style>
